<script lang="ts" setup>
  import { useUserStore } from '@/stores/user'
  import { io, type Socket } from 'socket.io-client'
  // 引入聊天室状态组件
  import roomStatus from './components/room-status.vue'
  import { ref } from 'vue'
  import type { OrderDetail } from '@/types/consult'
  import { orderDetailApi, uploadImageApi } from '@/apis/consult'
  import type { MsgData, MsgItem } from '@/types/room'
  import patientInfo from './components/patient-info.vue'
  import notifyInfo from './components/notify-info.vue'
  import messageInfo from './components/message-info.vue'
  import prescriptionInfo from './components/prescription-info.vue'
  import { nextTick } from 'vue'
  import rateInfo from './components/rate-info.vue'

  const store = useUserStore()
  const props = defineProps<{
    orderId: string
    payResult: string
  }>()

  // 所有的消息数组
  const messageList = ref<MsgItem[]>([])

  // 1. 如果支付失败, 拦截去个人中心
  if (props.payResult === 'false') {
    uni.switchTab({
      url: '/pages/my/index',
    })
  }

  // 2. 建立socket.io的连接
  const socket: Socket = io('https://consult-api.itheima.net', {
    auth: { token: 'Bearer ' + store.user.token },
    query: { orderId: props.orderId },
    transports: ['websocket', 'polling'],
    timeout: 5000,
  })

  socket.on('connect', () => {
    console.log('连接建立成功')
  })

  socket.on('error', (err) => {
    console.log('连接出现问题', err)
  })

  socket.on('disconnect', () => {
    console.log('断开连接')
  })

  // 3. 根据订单id获取订单详情
  const orderDetail = ref<OrderDetail>({} as OrderDetail)
  const getOrderDetail = async () => {
    if (!props.orderId) return uni.showToast({ title: '订单id不存在' })
    const res = await orderDetailApi(props.orderId)
    orderDetail.value = res
    // console.log(orderDetail.value)
  }
  getOrderDetail()
  // 监听订单状态的变化
  socket.on('statusChange', getOrderDetail)

  // 4. 获取默认消息
  socket.on('chatMsgList', (res: MsgData) => {
    // 4.1 判断
    if (res.code !== 10000) return uni.showToast({ title: '获取历史消息失败' })
    console.log(res.data)
    // 4.2 处理消息分组中的数据放入数组
    res.data?.forEach((item) => {
      messageList.value.push(
        {
          id: item.createTime,
          msgType: 31,
          msg: {
            content: item.createTime,
          },
        },
        ...item.items!
      )
    })
    // console.log(messageList.value)
  })

  // 5. 接收医生发送的消息
  socket.on('receiveChatMsg', (msg: MsgItem) => {
    // 5.1 标明消息已读
    socket.emit('updateMsgStatus', msg.id)
    // 5.2 把消息追加到消息数组
    messageList.value.push(msg)

    // 5.3 让滚动视图滚动到最后
    // vue中数据驱动视图, 数据是同步更新, 视图是异步更新
    // 数据更新了视图也更新了 就会触发nextTick函数的执行
    nextTick(() => {
      sp.value = 'item' + (messageList.value.length - 1)
    })
  })

  // 6. 发送文字消息给服务器
  const textMessage = ref('')
  const onConfirm = () => {
    // console.log(textMessage.value);
    // 6.1 判断是否有文字
    if (textMessage.value.trim() === '')
      return uni.showToast({ title: '不能发送空消息', icon: 'none' })

    // 6.2 把文字包装成一条消息发给服务器
    socket.emit('sendChatMsg', {
      from: store.user.id,
      to: orderDetail.value.docInfo?.id,
      msgType: 1,
      msg: {
        content: textMessage.value,
      },
    })

    // 6.3 清空输入框
    textMessage.value = ''
  }

  // 7. 发送图片消息
  const onSendImg = async () => {
    // 7.1 判断医生的状态
    if (orderDetail.value.status !== 3) {
      return uni.showToast({ title: '当前医生不在接诊状态', icon: 'none' })
    }

    // 7.2 获取图片文件完成上传得到图片的url地址
    const temp = await uni.chooseImage({
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
    })
    const res = await uploadImageApi(temp.tempFilePaths[0])

    // 7.3 把图片的Url包装成一个图片消息发给服务器
    socket.emit('sendChatMsg', {
      from: store.user.id,
      to: orderDetail.value.docInfo?.id,
      msgType: 4,
      msg: {
        picture: res,
      },
    })
  }

  // 8. 滚动到最底部
  const sp = ref('')
</script>

<template>
  <view class="room-page">
    <!-- 聊天室状态组件 -->
    <room-status
      v-if="orderDetail.id"
      :status="orderDetail.status"
      :status-value="orderDetail.statusValue"
      :countdown="orderDetail.countdown"
    />

    <scroll-view
      refresher-enabled
      refresher-background="#f2f2f2"
      scroll-y
      style="flex: 1; overflow: hidden"
      :scroll-into-view="sp"
    >
      <!-- <view > -->
      <!-- 此处将来填充更多代码... -->
      <view
        class="message-container"
        v-for="(item, index) in messageList"
        :key="item.id"
        :id="`item${index}`"
      >
        <!-- 患者病情消息 -->
        <patient-info :info="item.msg?.consultRecord!" v-if="item.msgType === 21" />
        <!-- 通知消息 -->
        <notify-info v-if="item.msgType! >= 31" :msg-type="item.msgType!">
          {{ item.msg?.content }}
        </notify-info>
        <!-- 文字和图片消息 -->
        <message-info v-if="item.msgType! <= 4" :info="item" :type="item.msgType!" />
        <!-- 处方消息 -->
        <prescription-info v-if="item.msgType === 22" :info="item.msg?.prescription!" />
      </view>
      <!-- </view> -->
      <scroll-view
        refresher-enabled
        refresher-background="#f2f2f2"
        scroll-y
        style="flex: 1; overflow: hidden"
      >
        <view class="message-container">
          <template v-for="message in messageList" :key="message.id">
            <!-- 医生评价 -->
            <rate-info v-if="message.msgType === 23"></rate-info>

            <!-- 此处将来填充更多代码... -->
          </template>
        </view>
      </scroll-view>
    </scroll-view>

    <!-- 发送消息 -->
    <view class="message-bar">
      <template v-if="true">
        <uni-easyinput
          v-model="textMessage"
          :disabled="orderDetail.status !== 3"
          :clearable="false"
          :input-border="false"
          placeholder-style="font-size: 32rpx; color: #c3c3c5;"
          placeholder="问医生"
          @confirm="onConfirm"
        />
        <view class="image-button">
          <uni-icons size="40" color="#979797" type="image" @click="onSendImg"></uni-icons>
        </view>
      </template>
      <button v-else class="uni-button">咨询其它医生</button>
    </view>
  </view>
</template>

<style lang="scss">
  @import './index.scss';
</style>
